fix dotnet time conversion (#784)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Mon, 6 Dec 2021 23:37:53 +0000 (16:37 -0700)
committerGitHub <noreply@github.com>
Mon, 6 Dec 2021 23:37:53 +0000 (16:37 -0700)
defs.h
reference/dotnet.csv [new file with mode: 0644]
reference/dotnet~csv.csv [new file with mode: 0644]
testo.d/unitconversion.test
util.cc
xcsv.cc
xmldoc/chapters/styles.xml

diff --git a/defs.h b/defs.h
index 7ee53fd0960a46a1cd8339a5d32e105ac65c839f..820232e0dba34c0847e4ec0980b22b458e02f73c 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -1113,7 +1113,7 @@ time_t mklocaltime(struct tm* t);
 time_t mkgmtime(struct tm* t);
 bool gpsbabel_testmode();
 gpsbabel::DateTime current_time();
-void dotnet_time_to_time_t(double dotnet, time_t* t, int* millisecs);
+QDateTime dotnet_time_to_qdatetime(long long dotnet);
 const char* get_cache_icon(const Waypoint* waypointp);
 const char* gs_get_cachetype(geocache_type t);
 const char* gs_get_container(geocache_container t);
diff --git a/reference/dotnet.csv b/reference/dotnet.csv
new file mode 100644 (file)
index 0000000..80fda5a
--- /dev/null
@@ -0,0 +1,6 @@
+0,40,105 # .net epoch midnight Jan 1, 1
+4999,40.5,105.5 # should round down
+5001,40.5,105.5 # should round up
+864000000000,41,106 # (60sec/min * 60min/hr * 24hr/day) / 100e-9 sec = midnight Jan 2, 1.
+637739532350000000,42,107 # GMT / UTC Date Time 2021-12-01 11:00:35 + 0.0000000 second
+
diff --git a/reference/dotnet~csv.csv b/reference/dotnet~csv.csv
new file mode 100644 (file)
index 0000000..87a80ba
--- /dev/null
@@ -0,0 +1,6 @@
+No,Latitude,Longitude,Name,Date,Time\r
+1,40.000000,105.000000,"WPT001",0001/01/01,00:00:00\r
+2,40.500000,105.500000,"WPT002",0001/01/01,00:00:00\r
+3,40.500000,105.500000,"WPT003",0001/01/01,00:00:00.001\r
+4,41.000000,106.000000,"WPT004",0001/01/02,00:00:00\r
+5,42.000000,107.000000,"WPT005",2021/12/01,11:00:35\r
index 326d7d63f7b97a515e99be2859f4cc3b4b880d69..9266da8380642ad8d291bc535b3d16736c8836e3 100644 (file)
@@ -66,3 +66,16 @@ echo 'OFIELD PATH_DISTANCE_NAUTICAL_MILES,"","%.6e"' >> ${TMPDIR}/distance3.styl
 
 gpsbabel -t -i xcsv,style=${TMPDIR}/distance3.style -f ${REFERENCE}/distance3.csv -o xcsv,style=${TMPDIR}/distance3.style -F ${TMPDIR}/distance3~csv.csv
 compare ${REFERENCE}/distance3~csv.csv ${TMPDIR}/distance3~csv.csv
+
+echo 'DESCRIPTION      dotnet test' > ${TMPDIR}/dotnet.style
+echo 'EXTENSION        csv' >> ${TMPDIR}/dotnet.style
+echo 'DATATYPE WAYPOINT' >> ${TMPDIR}/dotnet.style
+echo 'FIELD_DELIMITER          COMMA' >> ${TMPDIR}/dotnet.style
+echo 'RECORD_DELIMITER NEWLINE' >> ${TMPDIR}/dotnet.style
+echo 'BADCHARS COMMA' >> ${TMPDIR}/dotnet.style
+echo 'IFIELD   NET_TIME, "","%lld"' >> ${TMPDIR}/dotnet.style
+echo 'IFIELD   LAT_DECIMAL,"","%.9f"' >> ${TMPDIR}/dotnet.style
+echo 'IFIELD   LON_DECIMAL,"","%.9f"' >> ${TMPDIR}/dotnet.style
+gpsbabel -i xcsv,style=${TMPDIR}/dotnet.style -f ${REFERENCE}/dotnet.csv -o unicsv,utc=0 -F ${TMPDIR}/dotnet.csv
+compare ${REFERENCE}/dotnet~csv.csv ${TMPDIR}/dotnet.csv
+
diff --git a/util.cc b/util.cc
index 7db6af8a8b9379ac9a1c4d66a3f93c68a6b946b8..fb9921a96b86b9f04d2a2bc7f4206fd9d76b2819 100644 (file)
--- a/util.cc
+++ b/util.cc
@@ -765,23 +765,13 @@ current_time()
  * internals and since we're in the GPS biz, timestamps before 1/1/1970 aren't
  * that interesting to us anyway.
  */
-#define EPOCH_TICKS 621355968000000000.0
-void dotnet_time_to_time_t(double dotnet, time_t* t, int* millisecs)
+QDateTime dotnet_time_to_qdatetime(long long dotnet)
 {
-  // TODO: replace this with better interface with normal return values
-  // and called via a QDateTime.
-  *t = (dotnet - EPOCH_TICKS) / 10000000.;
-#if LATER
-  // TODO: work out fractional seconds.
-  if (millisecs) {
-    *millisecs = dotnet % 10000;
-  }
-#else
-  (void)millisecs;
-#endif
+  QDateTime epoch = QDateTime(QDate(1, 1, 1), QTime(0, 0, 0), Qt::UTC);
+  qint64 millisecs = (dotnet + 5000)/ 10000;
+  return epoch.addMSecs(millisecs);
 }
 
-
 /*
  * Return a pointer to a constant string that is suitable for icon lookup
  * based on geocache attributes.   The strings used are those present in
diff --git a/xcsv.cc b/xcsv.cc
index 048bb0a144e1b78cb4df6969f779e6692cf5cca5..c3d0fc9e5e6f869442ca595b8b9df98060085ed4 100644 (file)
--- a/xcsv.cc
+++ b/xcsv.cc
@@ -641,9 +641,11 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
     wpt->SetCreationTime(xml_parse_time(s));
     break;
   case XcsvStyle::XT_NET_TIME: {
-    fatal("XT_NET_TIME can't have possibly ever worked.");
-//    time_t tt = wpt->GetCreationTime();
-//    dotnet_time_to_time_t(atof(s), &tt, &wpt->microseconds);
+    bool ok;
+    wpt->SetCreationTime(dotnet_time_to_qdatetime(value.toLongLong(&ok)));
+    if (!ok) {
+      warning("parse of string '%s' on line number %d as NET_TIME failed.\n", s, line_no);
+    }
   }
   break;
   case XcsvStyle::XT_GEOCACHE_LAST_FOUND:
index f18b910d8ed269e3e8c2e937a65947c39b861e37..49c21cf023bec107a979d688ae0e92b718433692 100644 (file)
@@ -928,7 +928,7 @@ longitude)
 </para>
          <para>example:
 </para>
-         <screen format="linespecific">IFIELD NET_TIME,&quot;&quot;,&quot;%f&quot;
+         <screen format="linespecific">IFIELD NET_TIME,&quot;&quot;,&quot;%lld&quot;
 </screen>
       </section>
       <section id="style_def_geodiff">